package org.carl.component.job.service

import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONArray
import com.alibaba.fastjson.JSONObject
import com.xxl.job.core.biz.model.ReturnT
import com.xxl.job.core.executor.XxlJobExecutor
import org.carl.component.job.constant.PlatForm
import org.carl.component.job.core.XxljobInitialRunner
import org.carl.component.job.vo.XxlJobGroup
import org.carl.component.job.vo.XxlJobInfo
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.stereotype.Component

/**
 * email carl.chen@bk.ru
 * @Author: 陈青松
 * @Date: 2019/2/21 15:42
 */
@ConditionalOnBean(value = [XxlJobExecutor::class])
@Component
open class JobConfigService: JobService() {
    companion object {
        val LOG = LoggerFactory.getLogger(this.javaClass)
    }
    /**
     * 任务详细
     */
    @Autowired
    val jobInfoService: JobInfoService? = null
    /**
     * 任务组
     */
    @Autowired
    val jobGroupService: JobGroupService? = null
    /**
     * 应用名称
     */
    @Value("\${spring.application.name}")
    val appName:String?=null
    /**
     * 初始化登录
     */
    fun login():Unit{
        XxljobInitialRunner.LOG.info("初始化xxljob登录")
        val loginRes: ResponseEntity<String> = jobInfoService?.login()!!
        loginRes.let {
            if (loginRes.statusCode == HttpStatus.OK) {
                val httpHeaders: HttpHeaders = loginRes.headers
                val set_cookie = httpHeaders.get(HttpHeaders.SET_COOKIE)
                val joddCookie: jodd.http.Cookie? = jodd.http.Cookie(set_cookie.toString())
                PlatForm.COOKIE="XXL_JOB_LOGIN_IDENTITY=${joddCookie!!.value}"
                XxljobInitialRunner.LOG.info("Xxljob登录成功,Cookie:${PlatForm.COOKIE}")
            }
        }
    }

    /**
     * 初始化任务组
     */
    fun initGroupData():Unit{
        //查找所有的group info
        val allGroup = jobGroupService?.findAll()
        allGroup?.let {
            var xxlJobGroupList: MutableList<XxlJobGroup>? = mutableListOf()
            val body = allGroup.body
            val returnT = JSON.parseObject(body, ReturnT::class.java)
            returnT?.let { t ->
                if (t.code == 200 && t.content is JSONArray) {
                    val jas: JSONArray = t.content as JSONArray
                    jas?.forEach { i ->
                        val xjg: XxlJobGroup = JSONObject.parseObject(JSON.toJSONString(i), XxlJobGroup::class.java)
                        xxlJobGroupList!!.add(xjg)
                    }
                }
                PlatForm.XXLJOB_GROUP_LIST = xxlJobGroupList
            }
        }
    }
    /**
     * 初始化任务核心数据并返回最大的顺序号
     */
    fun initLocalJobConfigData():Int{
        //是否已经注册
        var order:Int=0
        PlatForm.XXLJOB_GROUP_LIST!!.forEach {
            if(it.order> order!!){
                order=it.order
            }
            if(it.appname.equals(appName)){
                PlatForm.LOCAL_GROUP_REGISTERED=true
                PlatForm.LOCAL_GROUP_ID=it.id
            }
        }
        return order
    }

    /**
     * 注册本地任务组
     */
    fun regLocalJobGroup(): ReturnT<*>? {
        if(appName==null){
            throw Error("Invalid application name,Please configure!!")
        }
        var order=initLocalJobConfigData()
        if(PlatForm.LOCAL_GROUP_REGISTERED){
            LOG.info("Local Job Group Already registered")
            return null
        }else{
            LOG.info("Local Job Group Start registration")
        }
        var xxlJobGroup=XxlJobGroup()
        xxlJobGroup.appname=appName
        xxlJobGroup.order=++order
        xxlJobGroup.title=appName
        //添加任务组
        LOG.debug("注册本地任务组:${JSON.toJSONString(xxlJobGroup)}")
        val responseEntity = jobGroupService!!.save(xxlJobGroup)
        val returnT = handleResponseEntity(responseEntity)
        LOG.info("注册任务组结果:${returnT}")
        return returnT
    }

    /**
     * 初始化任务集合
     */
    fun initJobInfoList():Unit{
        val jobs = jobInfoService!!.getJobsByGroup(PlatForm.LOCAL_GROUP_ID!!)
        PlatForm.JOB_LIST= jobs as List<XxlJobInfo>?
    }
}